﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Threading;
using System.Net;
using UDP;
using System.Runtime.InteropServices;

namespace XDMasterNetPlayer
{
    public enum PlayerDataType { NEW_CONNECT, FRAME};
    public struct XDPlayerData
    {

        public PlayerDataType type;
        public double data;
    };
    
    class XDPlayerSocket
    {
        private Master_Form parent;
        private Server udpSock = null;
       int port = 9002;
       public XDPlayerData recvPlayerData;
       
       public string strSlaverIP;
       public int nSlaverPort;
       public XDPlayerSocket(Master_Form form)
       {
           parent = form;

       }
      
         
  
       public bool Create(int port)
       {
           this.port = port;
           udpSock = new UDP.Server(new IPEndPoint(IPAddress.Any, port));
           if (udpSock == null)
               return false;
           udpSock.RecvDatagram += new UDP.NetEventArgsHandler(UDP_RecvDatagram);
           return true;
       }
       public bool Send(XDPlayerData data)
        {
            byte[] bytes = rawSerialize(data);
            IPEndPoint endpoint = new IPEndPoint(IPAddress.Parse(strSlaverIP), nSlaverPort);
            try
            {
                udpSock.SendTo(bytes, endpoint);
                return true;
            }
            catch (Exception err)
            {
                return false;
            }
        }
        protected void UDP_RecvDatagram(object sender, UDP.NetEventArgs e)
        {
            recvPlayerData = rawDeserialize(e.Buff);
            Object[] list = { this, System.EventArgs.Empty };
            parent.getPictureBox().BeginInvoke(new EventHandler(parent.pausePlayerData), list); 
            
        }
        private static byte[] rawSerialize(object obj)
        {
            int rawsize = Marshal.SizeOf(obj);
            IntPtr buffer = Marshal.AllocHGlobal(rawsize);
            Marshal.StructureToPtr(obj, buffer, false);
            byte[] rawdatas = new byte[rawsize];
            Marshal.Copy(buffer, rawdatas, 0, rawsize);
            Marshal.FreeHGlobal(buffer);

            return rawdatas;
        }
        private static XDPlayerData rawDeserialize(byte[] rawdatas)
        {
            Type anytype = typeof(XDPlayerData);
            int rawsize = Marshal.SizeOf(anytype);

            if (rawsize > rawdatas.Length)
                return new XDPlayerData();

            IntPtr buffer = Marshal.AllocHGlobal(rawsize);
            Marshal.Copy(rawdatas, 0, buffer, rawsize);
            object retobj = Marshal.PtrToStructure(buffer, anytype);
            Marshal.FreeHGlobal(buffer);

            return (XDPlayerData)retobj;
        }
    }
}
